package com.security.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @Author lhj
 * @Date 2021-08-26 11:11
 */
@EnableWebSecurity   // 开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //首页所有人可以访问，功能页只有对应权限的人才能访问
        //请求授权的规则~~
        http.authorizeRequests()
                //任何人都可以进入首页
                .antMatchers("/").permitAll()
                //进入/level1下的所有页面需要有vip1权限
                .antMatchers("/level1/**").hasRole("vip1")
                //进入/level2下的所有页面需要有vip2权限
                .antMatchers("/level2/**").hasRole("vip2")
                //进入/level3下的所有页面需要有vip3权限
                .antMatchers("/level3/**").hasRole("vip3");

        //自定义登录页
        http.formLogin()
                .usernameParameter("username")//表单提交的用户名name
                .passwordParameter("password")//表单提交的密码name
                .loginPage("/toLogin") //登录页面
                .loginProcessingUrl("/login")//处理登录请求的Controller(这个是Spring Security自带的)
                .failureForwardUrl("/toLogin");//登录失败请求的地址
        //注销成功之后到哪
        http.logout().logoutSuccessUrl("/");
        //用户授权(自定义403页面)在配置类里面进行配置即可
        http.exceptionHandling().accessDeniedPage("/error");

        //关闭csrf
        http.csrf().disable();
    }

    //认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //  在新版本的SpringSecurity中新增了许多加密方法，不使用加密的话就会出现异常如果不使用加密需要在密码前面加上{noop}
        //      这个例子模拟的是内存中的用户，真正开发中我们可以使用数据库
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("li")
                .password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2")

                .and().withUser("root")

                .password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2", "vip3")
                .and().withUser("guest")

                .password(new BCryptPasswordEncoder().encode("123")).roles("vip1");

    }
}
